package inet.db.tennis.buffer;

import java.math.BigDecimal;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;

import inet.db.tennis.TennisCategory;
import inet.db.tennis.TennisCategoryDAO;
import inet.db.tennis.TennisChampion;
import inet.db.tennis.TennisChampionDAO;
import inet.db.tennis.TennisPlayer;
import inet.db.tennis.TennisPlayerDAO;

public class TennisBuffer {
	private static final long CACHE_TIMEOUT = 10*60*1000;//10 mins
    private static long loadTime = System.currentTimeMillis();
    public static boolean isTimeout() {
        long currTime = System.currentTimeMillis();
        if ( (currTime - loadTime) > CACHE_TIMEOUT) {
            return true;
        }
        return false;
    }
    
    private static TennisPlayerDAO playerDAO = new TennisPlayerDAO();
    private static TennisChampionDAO championDAO = new TennisChampionDAO();
    private static TennisCategoryDAO categoryDAO = new TennisCategoryDAO();
    
    private static boolean isPlayerLoading = false;
    private static boolean isChampionLoading = false;
    
    private static Map playerTableId = new Hashtable();
    
    // Champion
    private static Map championTable = new Hashtable(); //code - FootballChampion
    private static Map championIdTable = new Hashtable(); //id - FootballChampion
    private static Vector championList = new Vector();
    
    public static Vector getChampionList() {
    	if(isTimeout() || championList == null) {
    		load();
    	}
        while (isPlayerLoading) {
            try {
                System.out.println("...wait for champion loading...");
                Thread.sleep(500);
            } catch (Exception ex) {}
        }

        return championList;
    }
    
    public static TennisChampion getChampionFromId(BigDecimal championId) {
    	if (championId == null) return null;
    	if(isTimeout() || championIdTable == null) {
    		load();
    	}
    	while (isPlayerLoading) {
    		try {
    			System.out.println("...wait for champion loading...");
    			Thread.sleep(500);
    		} catch (Exception ex) {}
    	}
    	
    	return (TennisChampion) championIdTable.get(championId);
    }
    
    public static TennisChampion getChampionFromCode(String code) {
    	if (code == null) return null;
    	if(isTimeout() || championTable == null) {
    		load();
    	}
    	while (isPlayerLoading) {
    		try {
    			System.out.println("...wait for champion loading...");
    			Thread.sleep(500);
    		} catch (Exception ex) {}
    	}
    	
    	return (TennisChampion) championTable.get(code);
    }
    
    public static TennisPlayer getPlayerFromId(BigDecimal playerId) {
    	if (playerId == null) return null;
    	if(isTimeout() || playerTableId == null) {
    		load();
    	}
    	while (isPlayerLoading) {
    		try {
    			System.out.println("...wait for player loading...");
    			Thread.sleep(500);
    		} catch (Exception ex) {}
    	}
    	
    	return (TennisPlayer) playerTableId.get(playerId);
    }
    
    private static void loadChampion() {

    	Vector v = new Vector();
        Map m = new Hashtable();
        Map m2 = new Hashtable();
        TennisChampion champion = null;
        Vector<TennisChampion> cChampion = championDAO.findAll();

        try {
            for (Iterator itt = cChampion.iterator(); itt.hasNext(); ) {
            	champion = (TennisChampion) itt.next();
                if (champion == null) continue;
                //Code
                v.add(champion);
	            m.put(champion.getCode(), champion);
	            m2.put(champion.getId(), champion);
            }

            isChampionLoading = true;
            championTable.clear();
            championTable = m;

            championIdTable.clear();
            championIdTable = m2;

            championList.clear();
            championList = v;
            
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
        	isChampionLoading = false;
        }
    }
    
    private static void loadPlayer() {
    	
    	Map codeTable = new Hashtable();
    	TennisPlayer player = null;
    	Vector<TennisPlayer> cPlayer = playerDAO.findAll();
    	
    	try {
    		for (Iterator itt = cPlayer.iterator(); itt.hasNext(); ) {
    			player = (TennisPlayer) itt.next();
    			if (player == null) continue;
    			//Code
    			codeTable.put(player.getId(), player);
    		}
    		
    		isPlayerLoading = true;
    		playerTableId.clear();
    		//playerTableId.putAll(codeTable);
    		playerTableId = codeTable;
    		
    	} catch (Exception ex) {
    		ex.printStackTrace();
    	} finally {
    		isPlayerLoading = false;
    	}
    }
    
    public static void load() {
        try {
            System.out.println("~~LOAD player and champion ...");
            loadChampion();
            loadPlayer();
            System.out.println("   Player  : " + playerTableId.size());
            System.out.println("   Champion code : " + championTable.size());

            loadTime = System.currentTimeMillis();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    static {
        load();
    }
    
    public static TennisChampion reloadChampion(String championCode) {
        System.out.println("Champion " + championCode + " is timeout --> reload");
        TennisChampion newChampion = championDAO.getRow(championCode);

        if (newChampion == null) return null;

        try {
            isChampionLoading = true;
            championTable.put(championCode, newChampion);
            championIdTable.put(newChampion.getId(), newChampion);
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
        	isChampionLoading = false;
        }
        return newChampion;
    }
    
    public static TennisPlayer reloadPlayer(BigDecimal playerId) {
    	System.out.println("Player " + playerId + " is timeout --> reload");
    	TennisPlayer newPlayer = playerDAO.getRow(playerId);
    	
    	if (newPlayer == null) return null;
    	
    	try {
    		isPlayerLoading = true;
    		playerTableId.put(playerId, newPlayer);
    	} catch (Exception ex) {
    		ex.printStackTrace();
    	} finally {
    		isPlayerLoading = false;
    	}
    	return newPlayer;
    }
    
}
